package com.bdzl.auth.common.exception;

import com.bdzl.pub.util.param.R;
import com.bdzl.auth.common.utils.StringUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authz.AuthorizationException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.validation.BindException;
import org.springframework.web.HttpRequestMethodNotSupportedException;
import org.springframework.web.bind.MissingServletRequestParameterException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

import javax.validation.ConstraintViolationException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
 * 异常处理器
 *
 */
@RestControllerAdvice
public class BDExceptionHandler {
	private Logger logger = LoggerFactory.getLogger(getClass());

	/**
	 * 自定义异常
	 */
	@ExceptionHandler(BDException.class)
	public R handleBDException(BDException e) {
		return R.error(String.valueOf(e.getCode()),e.getMessage());
	}

	@ExceptionHandler(DuplicateKeyException.class)
	public R handleDuplicateKeyException(DuplicateKeyException e) {
		logger.error(e.getMessage(), e);
		return R.error(R.处理失败,"数据库中已存在该记录");
	}

	@ExceptionHandler(org.springframework.web.servlet.NoHandlerFoundException.class)
	public R noHandlerFoundException(org.springframework.web.servlet.NoHandlerFoundException e) {
		logger.error(e.getMessage(), e);
		return R.error("没找找到页面");
	}

	@ExceptionHandler(AuthorizationException.class)
	public R handleAuthorizationException(AuthorizationException e) {
		logger.error(e.getMessage(), e);
		return R.error(R.用户状态异常,"未授权");
	}
	@ExceptionHandler(AuthenticationException.class)
	public R AuthenticationException(AuthenticationException e) {
		logger.error(e.getMessage(), e);
		return R.error(R.用户状态异常,e.getMessage());
	}

	@ExceptionHandler(Exception.class)
	public R handleException(Exception e) {
		logger.error(e.getMessage(), e);
		return R.error("服务器错误，请联系管理员");
	}

	@ExceptionHandler(NullPointerException.class)
	public R handle(NullPointerException e) {
		e.printStackTrace();
		logger.error(e.getMessage(), e);
		return R.error(R.处理失败,"没有相关数据");
	}

	@ExceptionHandler(HttpRequestMethodNotSupportedException.class)
	public R handle(HttpRequestMethodNotSupportedException e) {
		logger.error(e.getMessage(), e);
		return R.error(R.程序异常,e.getMethod()+"请求方式错误,应该为以下请求方式"+ Arrays.toString(e.getSupportedMethods()));
	}

	@ExceptionHandler(MissingServletRequestParameterException.class)
	public R handle(MissingServletRequestParameterException e) {
		logger.error(e.getMessage(), e);
		return R.error(R.程序异常,"请填写"+e.getParameterName()+"参数,类型为"+e.getParameterType());
	}

	@ExceptionHandler(BindException.class)
	public R handle(BindException e) {
		List<String> message=new ArrayList<>();
		//在这里，我们判断参数是否通过校验
		e.getBindingResult().getAllErrors().forEach(item -> message.add(item.getDefaultMessage()));
		logger.error(e.getMessage(), e);
		return R.error(R.程序异常,this.toMessage(message.toArray()));
	}

	@ExceptionHandler(ConstraintViolationException.class)
	public R handle(ConstraintViolationException e) {
		List<String> message=new ArrayList<>();
		//在这里，我们判断参数是否通过校验
		e.getConstraintViolations().forEach(item -> message.add(item.getMessage()));
		logger.error(e.getMessage(), e);
		return R.error(R.程序异常,this.toMessage(message.toArray()));
	}

	private String toMessage(Object[] message){
		return StringUtils.strip(Arrays.toString(message),"[]");
	}
}
